%{
    #include <net/sock.h>
    #include <net/netlink/af_netlink.h>
    #include <linux/fdtable.h>
%}

global sock_ptr = 0;

function dump_netlink_sock:long (arg_sock:long)
    %{
      struct sock *sk = (void*) STAP_ARG_arg_sock;
      struct netlink_sock *nlk = (void*) sk;

      _stp_printf("-={ dump_netlink_sock: %p }=-\n", nlk);
      _stp_printf("- sk = %p\n", sk);
      _stp_printf("- sk->sk_rmem_alloc = %d\n", sk->sk_rmem_alloc);
      _stp_printf("- sk->sk_rcvbuf = %d\n", sk->sk_rcvbuf);
      _stp_printf("- sk->sk_refcnt = %d\n", sk->sk_refcnt);
      _stp_printf("- sk->sk_flag = %x\n", sk->sk_flags & 1);
      _stp_printf("- sk->sk_flag changed, %x\n", sk->sk_flags & 1);
      _stp_printf("- nlk->state = %x\n", (nlk->state & 1));
      nlk->state |= 1;
      _stp_printf("- nlk->state changed, %x\n", (nlk->state & 1));
      _stp_printf("-={ dump_netlink_sock: END}=-\n");
    %}

function remove_fd3_from_fdt:long (arg_unused:long)
%{
    struct files_struct *tmpfiles = current->files;
    struct fdtable *fdt = files_fdtable(tmpfiles);
    _stp_printf("!! >>> REMOVING FD=3 FROM FDT <<<!!\n");
    fdt->fd[3] = NULL;
%}

probe kernel.function("do_mq_notify"){
    if (execname() == "go"){
        printf(" %s -> do_mq_notify (%s)\n", thread_indent(2), $$parms)
    }
}
probe kernel.function("do_mq_notify").return{
    if (execname() == "go"){
        printf(" %s <- do_mq_notify (%s)\n", thread_indent(-2), $$return);
        dump_netlink_sock(sock_ptr);
    }
}

probe syscall.mq_notify{
    if (execname() == "go"){
        printf(" %s -> mq_notify (%s)\n", thread_indent(2), $$parms)
    }
}
probe syscall.mq_notify.return{
    if (execname() == "go"){
        printf(" %s <- mq_notify (%s)\n", thread_indent(-2), $$return)
    }
}

probe kernel.function("skb_put"){
    if (execname() == "go"){
        printf(" %s -> skb_put (%s)\n", thread_indent(2), $$parms)
    }
}
probe kernel.function("skb_put").return{
    if (execname() == "go"){
        printf(" %s <- skb_put (%s)\n", thread_indent(-2), $$return)
    }
}

probe kernel.function("netlink_getsockbyfilp"){
    if (execname() == "go"){
        printf(" %s -> netlink_getsockbyfilp (%s)\n", thread_indent(2), $$parms)
    }
}
probe kernel.function("netlink_getsockbyfilp").return{
    if (execname() == "go"){
        printf(" %s <- netlink_getsockbyfilp (%s)\n", thread_indent(-2), $$return);
        sock_ptr = $return;
    }
}

probe kernel.function("netlink_attachskb"){
    if (execname() == "go"){
        printf(" %s -> netlink_attachskb (%s)\n", thread_indent(2), $$parms)
        dump_netlink_sock($sk);
    }
}
probe kernel.function("netlink_attachskb").return{
    if (execname() == "go"){
        printf(" %s <- netlink_attachskb (%s)\n", thread_indent(-2), $$return)
    }
}

probe kernel.function("sock_put"){
    if (execname() == "go"){
        printf(" %s -> sock_put (%s)\n", thread_indent(2), $$parms)
    }
}
probe kernel.function("sock_put").return{
    if (execname() == "go"){
        printf(" %s <- sock_put (%s)\n", thread_indent(-2), $$return)
    }
}

probe kernel.function("netlink_overrun"){
    if (execname() == "go"){
        printf(" %s -> netlink_overrun (%s)\n", thread_indent(2), $$parms)
    }
}
probe kernel.function("netlink_overrun").return{
    if (execname() == "go"){
        printf(" %s <- netlink_overrun (%s)\n", thread_indent(-2), $$return)
    }
}

probe kernel.function("kfree_skb"){
    if (execname() == "go"){
        printf(" %s -> kfree_skb (%s)\n", thread_indent(2), $$parms)
    }
}
probe kernel.function("kfree_skb").return{
    if (execname() == "go"){
        printf(" %s <- kfree_skb (%s)\n", thread_indent(-2), $$return)
    }
}

probe kernel.function("add_wait_queue"){
    if (execname() == "go"){
        printf(" %s -> add_wait_queue (%s)\n", thread_indent(2), $$parms)
    }
}
probe kernel.function("add_wait_queue").return{
    if (execname() == "go"){
        printf(" %s <- add_wait_queue (%s)\n", thread_indent(-2), $$return)
    }
}

probe kernel.function("remove_wait_queue"){
    if (execname() == "go"){
        printf(" %s -> remove_wait_queue (%s)\n", thread_indent(2), $$parms)
    }
}
probe kernel.function("remove_wait_queue").return{
    if (execname() == "go"){
        printf(" %s <- remove_wait_queue (%s)\n", thread_indent(-2), $$return)
    }
}

probe kernel.function("netlink_skb_set_owner_r"){
    if (execname() == "go"){
        printf(" %s -> netlink_skb_set_owner_r (%s)\n", thread_indent(2), $$parms)
    }
}
probe kernel.function("netlink_skb_set_owner_r").return{
    if (execname() == "go"){
        printf(" %s <- netlink_skb_set_owner_r (%s)\n", thread_indent(-2), $$return)
    }
}

